﻿using System;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.Linq;
using System.Data.Linq.SqlClient;
using System.Linq.Dynamic;
using System.Linq;
using System.Text;
using IntraVision.Web;
using IntraVision.Web.Filter;
using IntraVision.Web.Security;
using Model;

public class ClientController : TableController<NotarialServiceDataContext, Client>
{
    public ClientController() { }

    protected override void EntityLoaded(NotarialServiceDataContext dc, Client entity)
    {
        
    }

    [AllowedRole("IsAdmin")]
    public override void List()
    {
        base.List();
    }

    public void Select()
    {
        ViewData["hidecb"] = ViewData["popup"] = true;
        RegisterScript("table.js", "jquery.multipleselect.js", "user/select.js");

        _ActionKey = Action;
        if (String.IsNullOrEmpty(Request["nolayout"]))
        {
            LayoutPath = "~/views/layouts/popup.haml";
            TemplatePath = "~/views/client/select.haml";
        }
        else TemplatePath = "~/views/_table/table.haml";

        ProcessTable();
    }

    public override void Create()
    {
        Response.Redirect("person.ivp/create");
    }

    protected override IQueryable ConvertQueryToResult(NotarialServiceDataContext dc, IQueryable<Client> query)
    {
        return (from q in query
                select new
                {
                    Id = q.Id,
                    Name = q.Name,
                    Info = q.Info,
                    IsNatural = q.IsNatural,
                    Type = q.Type,
                    IdStr = q.IdStr,
                    Cid = q.Cid,
                    IsCashless= q.IsCashless,
                    IsNotify = q.IsNotify,
                    NotifyComment = q.NotifyComment
                });
    }

    [AllowedRole("IsAdmin")]
    public override void View(string entityid)
    {
        if (!string.IsNullOrEmpty(entityid) && entityid.Length > 0)
        {
            int cid;
            if (Int32.TryParse(entityid, out cid))
                Response.Redirect(String.Format("{0}.ivp/view/{1}{2}", (Client.CheckIsNatural(cid) ? "person" : "company"), Client.GetIdByCid(cid), Request.Url.Query));
        }
    }

    public override void Delete()
    {
        if (String.IsNullOrEmpty(Request["id"]))
            throw new ArgumentException("Идентификатор записи не передан");

        //получаем массив id-шников из request'а
        string[] ids = null;
        if (Request["id"].IndexOf(',') > 0)
            ids = Request["id"].Split(',');
        else
            ids = new string[1] {Request["id"]};

        List<int> pList = new List<int>();
        List<int> cList = new List<int>();
        char type;
        int bid;

        //раскладываем id-шники по массивам сущностей
        foreach (string id in ids)        
            if (!string.IsNullOrEmpty(id) && id.Length > 0)
            {
                type = id[0];
                if (Int32.TryParse(id.TrimStart(type), out bid))
                {
                    switch (type)
                    {
                        case 'p':  //для сущности Personal
                            pList.Add(bid);  break;
                        case 'c': //для сущности Company
                            cList.Add(bid);  break;
                    }
                }
            }

        //вызываем метод удаления для каждой сущности
        try
        {
            DeleteClients<Person>(pList.ToArray());
            DeleteClients<Company>(cList.ToArray());
        }
        catch (SqlException ex)
        {
            var wex = SqlExceptionHelper.WrapException(ex);
            if (!string.IsNullOrEmpty(Request["json"]))
            {
                RenderJSON(new AJAXResult(wex));
                return;
            }
            else
                ViewData.Exceptions.Add(wex);
        }
        catch (Exception ex)
        {
            if (!string.IsNullOrEmpty(Request["json"]))
            {
                RenderJSON(new AJAXResult(ex));
                return;
            }
            else
                ViewData.Exceptions.Add(ex);
        }

        //в зависимости от типа запроса (ajax или нет) рендерим результат
        if (!string.IsNullOrEmpty(Request["json"]))
        {
            AJAXResult result = new AJAXResult();
            result.Id = Request["id"];
            RenderJSON(result);
        }
        else
            List();
    }

    private void DeleteClients<T>(int[] ids) 
        where T : class, IClient
    {
        if (ids.Length > 0)
            using (var dc = new NotarialServiceDataContext())
            {
                List<T> deleted = new List<T>();
                var table = dc.GetTable<T>();
                foreach (int i in ids)
                {
                    T entity = table.Where("Id = @0", i).FirstOrDefault();
                    if (entity != null)
                    {
                        deleted.Add(entity);
                        dc.GetTable<T>().DeleteOnSubmit(entity);
                    }
                }
                if (dc.GetChangeSet().Deletes.Count > 0)
                    dc.SubmitChanges();

                foreach (var entity in deleted)
                    Logger.WriteLog(dc, LogOperationType.ClientDelete, (Session["User"] as User).Id, null, null);
            }   
        return;
    }

    #region Поиск
    protected override IQueryable<Client> Search(IQueryable<Client> query)
    {
        var searchStr = State["tb_search"] != null ? State["tb_search"].Trim().ToLower() : "";
        if (!string.IsNullOrEmpty(searchStr))
        {
            int number;
            var search = String.Format("%{0}%", searchStr.Trim().ToLower());

            #region если в строке поиска есть пробел
            if (searchStr.IndexOf(' ') > -1)
            {
                //попытаемся конвертировать строки в int'ы
                var arr = searchStr.Split(new char[] {' '}, 2);
                int bufInt32;
                bool isNumber = true;
                for (int i = 0; i < arr.Length; i++)
                {
                    arr[i] = arr[i].Trim();
                    if (!Int32.TryParse(arr[i], out bufInt32) || bufInt32 < 0)                    
                        isNumber = false;                    
                }
                if (isNumber) //если конверсия удалась и в массиве два числа
                {
                    //для физ.лиц ищем первое число в серии, а второе в номере паспорта
                    //для юр. лиц просто ищем всю строку поиска в информации
                    query = query.Where(q => (SqlMethods.Like(q.Info, String.Format("%{0}% %",arr[0])) 
                                                && SqlMethods.Like(q.Info, String.Format("% %{0}%", arr[1]))
                                                && q.IsNatural) || (SqlMethods.Like(q.Info, search) && !q.IsNatural)
                                        );
                }
                else
                {
                    if (arr[1].IndexOf(' ') > -1) //если можно разбить 2-ю строку на две
                    {
                        var bufArr = arr[1].Split(new char[] {' '}, 2);
                        arr = new string[3] { arr[0], bufArr[0].Trim(), bufArr[1].Trim() };
                        query = query.Where(q => (SqlMethods.Like(q.Name, String.Format("%{0}% %", arr[0]))
                                                    && SqlMethods.Like(q.Name, String.Format("% %{0}%", arr[1]))
                                                    && SqlMethods.Like(q.Name, String.Format("% % %{0}%", arr[2]))
                                                    && q.IsNatural) || (SqlMethods.Like(q.Name, search) && !q.IsNatural)
                                            );

                    }
                    else
                        query = query.Where(q => (SqlMethods.Like(q.Name, String.Format("%{0}% %", arr[0]))
                                                    && SqlMethods.Like(q.Name, String.Format("% %{0}%", arr[1]))
                                                    && q.IsNatural) || (SqlMethods.Like(q.Name, search) && !q.IsNatural)
                                            );
                }
            }
            #endregion

            #region нет пробела в строке поиска
            else 
            {
                //в строке число
                if ((Int32.TryParse(searchStr, out number)) && number > 0)
                    query = query.Where(q => SqlMethods.Like(q.Info, search));
                else
                    query = query.Where(q => SqlMethods.Like(q.Name, search)); 

            }
            #endregion
        }
        return query;
    }
    #endregion
}
